package com.easonji.common.node;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import com.easonji.common.constant.enums.IsMenuEnum;
import com.easonji.common.util.StringUtils;

/**
 * @ClassName: MenuNode
 * @Description: 菜单的节点
 * @Author: LiuJun
 * @date: 2018/07/09 12:45
 * @Version: 1.0
 * @Copyright: Copyright (c) 2018 - 2019
 */
@SuppressWarnings("rawtypes")
public class MenuNode implements Comparable {

    /**
     * 节点id
     */
    private Integer id;

    /**
     * 父节点
     */
    private Integer parentId;

    /**
     * 节点名称
     */
    private String name;

    /**
     * 按钮级别
     */
    private Integer isMenu;

    /**
     * 按钮的排序
     */
    private Integer num;

    /**
     * 节点的url
     */
    private String url;

    /**
     * 节点图标
     */
    private String icon;

    /**
     * 子节点的集合
     */
    private List<MenuNode> children;

    /**
     * 查询子节点时候的临时集合
     */
    private List<MenuNode> linkedList = new ArrayList<MenuNode>();

    public MenuNode() {
        super();
    }

    public MenuNode(Integer id, Integer parentId) {
        super();
        this.id = id;
        this.parentId = parentId;
    }

    public String getIcon() {
        return icon;
    }

    public void setIcon(String icon) {
        this.icon = icon;
    }

    public static MenuNode createRoot() {
        return new MenuNode(0, -1);
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getParentId() {
        return parentId;
    }

    public void setParentId(Integer parentId) {
        this.parentId = parentId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public List<MenuNode> getChildren() {
        return children;
    }

    public void setChildren(List<MenuNode> children) {
        this.children = children;
    }

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }

    public Integer getIsMenu() {
        return isMenu;
    }

    public void setIsMenu(Integer isMenu) {
        this.isMenu = isMenu;
    }

    @Override
    public String toString() {
        return "{\"id\":\"" + id + "\",\"parentId\":\"" + parentId + "\",\"name\":\"" + name + "\",\"isMenu\":\""
                + isMenu + "\",\"num\":\"" + num + "\",\"url\":\"" + url + "\",\"icon\":\"" + icon
                + "\",\"children\":\"" + children.toString() + "\"} ";
    }

    @Override
    public int compareTo(Object o) {
        MenuNode menuNode = (MenuNode) o;
        Integer num = menuNode.getNum();
        if (num == null) {
            num = 0;
        }
        return this.num.compareTo(num);
    }

    /**
     * 构建整个菜单树
     *
     */
    public List<MenuNode> buildNodeTree(List<MenuNode> nodeList) {
        List<MenuNode> result = new ArrayList<>(2);
        for (MenuNode treeNode : nodeList) {
            // 一级目录查询子节点
            if (StringUtils.isEmpty(treeNode.getParentId()) || treeNode.getParentId() == 0) {
                List<MenuNode> linkedList = treeNode.findChildNodes(nodeList, treeNode.getId());
                if (linkedList.size() > 0) {
                    treeNode.setChildren(linkedList);
                }
                result.add(treeNode);
            }
        }
        return result;
    }

    /**
     * 查询子节点的集合
     */
    public List<MenuNode> findChildNodes(List<MenuNode> nodeList, Integer parentId) {
        if (nodeList == null && parentId == null) {
            return null;
        }
        for (Iterator<MenuNode> iterator = nodeList.iterator(); iterator.hasNext();) {
            MenuNode node = (MenuNode) iterator.next();
            // 根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (node.getParentId() != 0 && parentId.equals(node.getParentId())) {
                recursionFn(nodeList, node, parentId);
            }
        }
        return linkedList;
    }

    /**
     * 遍历一个节点的子节点
     */
    public void recursionFn(List<MenuNode> nodeList, MenuNode node, Integer pId) {
        // 得到子节点列表
        List<MenuNode> childList = getChildList(nodeList, node);
        // 判断是否有子节点
        if (childList.size() > 0) {
            if (node.getParentId().equals(pId)) {
                linkedList.add(node);
            }
            Iterator<MenuNode> it = childList.iterator();
            while (it.hasNext()) {
                MenuNode n = (MenuNode) it.next();
                recursionFn(nodeList, n, pId);
            }
        } else {
            if (node.getParentId().equals(pId)) {
                linkedList.add(node);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<MenuNode> getChildList(List<MenuNode> list, MenuNode node) {
        List<MenuNode> nodeList = new ArrayList<MenuNode>();
        Iterator<MenuNode> it = list.iterator();
        while (it.hasNext()) {
            MenuNode n = (MenuNode) it.next();
            if (n.getParentId().equals(node.getId())) {
                nodeList.add(n);
            }
        }
        return nodeList;
    }

    /**
     * 清除掉按钮级别的资源
     */
    public static List<MenuNode> clearBtn(List<MenuNode> nodes) {
        List<MenuNode> noBtns = new ArrayList<MenuNode>();
        for (MenuNode node : nodes) {
            if (node.getIsMenu() == IsMenuEnum.YES.getCode()) {
                noBtns.add(node);
            }
        }
        return noBtns;
    }

    /**
     * 构建菜单列表
     */
    @SuppressWarnings("unchecked")
    public static List<MenuNode> buildTitle(Boolean clearBtn, List<MenuNode> nodes) {
        if (clearBtn) {
            nodes = clearBtn(nodes);
        }
        List<MenuNode> menuNodes = new MenuNode().buildNodeTree(nodes);
        // 对菜单排序
        Collections.sort(menuNodes);
        // 对菜单的子菜单进行排序
        for (MenuNode menuNode : menuNodes) {
            if (menuNode.getChildren() != null && menuNode.getChildren().size() > 0) {
                Collections.sort(menuNode.getChildren());
            }
        }
        return menuNodes;
    }
}
